<template>
  <div class="dot-single-page">
    <div class="dot-container">
            <div class="page-header">
              <h1>DoT 单点检测</h1>
              <p class="subtitle">检测目标 IP 地址的 DoT (DNS over TLS) 支持情况及相关指标</p>
            </div>

            <!-- 搜索区域 -->
            <el-card class="search-card">
              <div class="search-area">
                <el-input
                  v-model="ipAddress"
                  placeholder="请输入目标 IP 地址，例如: 8.8.8.8"
                  :prefix-icon="Search"
                  clearable
                  @keyup.enter="handleSubmit"
                >
                  <template #append>
                    <el-button type="primary" @click="handleSubmit" :loading="loading">
                      {{ loading ? '检测中...' : '开始检测' }}
                    </el-button>
                  </template>
                </el-input>
              </div>
            </el-card>

            <!-- 错误提示 -->
            <el-alert
              v-if="error"
              :title="error"
              type="error"
              show-icon
              closable
              @close="error = ''"
              class="error-alert"
            />

            <!-- 结果展示区域 -->
            <div class="results-area" v-if="hasResults">
              <!-- 状态概览 -->
              <div class="status-overview">
                <el-result
                  :icon="resultIcon"
                  :title="resultTitle"
                  :sub-title="resultSubTitle"
                >
                  <template #extra>
                    <div class="quick-stats">
                      <div class="stat-item" :class="{ 'is-success': dotSupported }">
                        <el-icon><component :is="dotSupported ? 'CircleCheckFilled' : 'CircleCloseFilled'" /></el-icon>
                        <span>DoT 支持</span>
                      </div>
                      <div class="stat-item" :class="{ 'is-success': certValid }">
                        <el-icon><component :is="certValid ? 'CircleCheckFilled' : 'CircleCloseFilled'" /></el-icon>
                        <span>证书有效</span>
                      </div>
                    </div>
                  </template>
                </el-result>
              </div>

              <!-- 预警展示区域 -->
              <div class="warning-area" v-if="warnings.length > 0">
                <el-alert
                  title="安全预警"
                  type="warning"
                  :closable="false"
                  show-icon
                  class="warning-header"
                >
                  <template #default>
                    <div class="warning-content">
                      <div class="warning-grid">
                        <div 
                          v-for="warning in warnings" 
                          :key="warning.type"
                          class="warning-item"
                        >
                          <div class="warning-icon">
                            <el-icon><Warning /></el-icon>
                          </div>
                          <div class="warning-text">
                            <div class="warning-title">{{ warning.title }}</div>
                            <div class="warning-desc">{{ warning.description }}</div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </template>
                </el-alert>
              </div>

              <!-- 详细信息卡片 -->
              <el-row :gutter="20">
                <el-col :span="12">
                  <el-card class="detail-card">
                    <el-descriptions :column="1" border>
                      <el-descriptions-item v-for="item in leftItems" :key="item.label" :label="item.label">
                        <el-tag
                          :type="getTagType(item.value, item.label)"
                          :effect="getTagEffect(item.value)"
                        >
                          {{ formatValue(item) }}
                        </el-tag>
                      </el-descriptions-item>
                    </el-descriptions>
                  </el-card>
                </el-col>

                <el-col :span="12">
                  <el-card class="detail-card">
                    <el-descriptions :column="1" border>
                      <el-descriptions-item v-for="item in rightItems" :key="item.label" :label="item.label">
                        <el-tag
                          :type="getTagType(item.value, item.label)"
                          :effect="getTagEffect(item.value)"
                        >
                          {{ formatValue(item) }}
                        </el-tag>
                      </el-descriptions-item>
                    </el-descriptions>
                  </el-card>
                </el-col>
              </el-row>
            </div>

            <!-- 空状态 -->
            <el-empty
              v-else-if="!error"
              description="请输入 IP 地址开始检测"
              :image-size="200"
            >
              <template #image>
                <el-icon :size="64" color="#909399"><Search /></el-icon>
              </template>
            </el-empty>
    </div>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue'
import axios from 'axios'

import { Search, CircleCheckFilled, CircleCloseFilled, Warning } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'

// 响应式状态
const ipAddress = ref('')
const loading = ref(false)
const error = ref('')
const leftItems = ref([
  { label: '支持DoT', value: null },
  { label: '证书有效性', value: null },
  { label: '自签名证书', value: null },
  { label: '证书颁发机构', value: null },
  { label: '颁发机构国家', value: null },
  { label: '证书吊销状态', value: null },
  { label: 'TLS版本', value: null },
  { label: 'TLS加密套件', value: null }
])
const rightItems = ref([
  { label: '关联域名', value: null },
  { label: '证书主体', value: null },
  { label: '证书有效期（天）', value: null },
  { label: '公钥长度（bit）', value: null },
  { label: '证书签名算法', value: null },
  { label: '协议版本', value: null },
  { label: '是否有应答', value: null },
  { label: '响应时间（ms）', value: null }
])

// 预警状态
const warnings = ref([])

// 辅助函数
const isValidIP = (ip) => {
  const ipv4Regex = /^(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)){3}$/;
  const ipv6Regex = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::1|::)$/;
  return ipv4Regex.test(ip) || ipv6Regex.test(ip);
}

const formatValue = (item) => {
  // 特殊字段的处理
  if (item.label === '证书有效性') {
    if (item.value === true) return '有效'
    if (item.value === false) return '无效'
    return '未验证'
  }
  
  if (item.label === '自签名证书') {
    if (item.value === true) return '是'
    if (item.value === false) return '否'
    return '未验证'
  }
  
  if (item.label === '是否有应答') {
    if (item.value === true) return '有'
    if (item.value === false) return '无'
    return '未验证'
  }
  
  // 通用布尔值处理
  if (item.value === true) return '支持'
  if (item.value === false) return '不支持'
  if (item.value === null || item.value === undefined) return '未验证'
  
  // 对证书吊销状态字段进行特殊处理
  if (item.label === '证书吊销状态') {
    if (typeof item.value === 'string' && item.value.toUpperCase() === 'GOOD') return '未吊销'
    if (typeof item.value === 'string' && item.value.toUpperCase() !== 'GOOD' && item.value.trim() !== '') return '已吊销'
  }
  
  return item.value
}

const getTagType = (value, label) => {
  // 特殊字段的标签类型
  if (label === '证书有效性') {
    if (value === true) return 'success'
    if (value === false) return 'danger'
    return 'info'
  }
  
  if (label === '自签名证书') {
    if (value === true) return 'warning'  // 自签名证书用警告色
    if (value === false) return 'success'
    return 'info'
  }
  
  if (label === '是否有应答') {
    if (value === true) return 'success'
    if (value === false) return 'danger'
    return 'info'
  }
  
  // 通用布尔值处理
  if (value === true) return 'success'
  if (value === false) return 'danger'
  if (value === null || value === undefined) return 'info'
  
  // 对证书吊销状态字段进行特殊处理
  if (label === '证书吊销状态') {
    if (typeof value === 'string' && value.toUpperCase() === 'GOOD') return 'success'
    if (typeof value === 'string' && value.toUpperCase() !== 'GOOD' && value.trim() !== '') return 'danger'
  }
  
  return 'primary'
}

const getTagEffect = (value) => {
  if (value === null || value === undefined) return 'plain'
  return 'dark'
}

// 计算属性
const hasResults = computed(() => {
  return leftItems.value.some(item => item.value !== null) ||
         rightItems.value.some(item => item.value !== null)
})

const dotSupported = computed(() => {
  const item = leftItems.value.find(item => item.label === '支持DoT')
  return item ? item.value : false
})

const certValid = computed(() => {
  const item = leftItems.value.find(item => item.label === '证书有效性')
  return item ? item.value : false
})

const resultIcon = computed(() => {
  if (!hasResults.value) return 'info'
  return dotSupported.value && certValid.value ? 'success' : 'warning'
})

const resultTitle = computed(() => {
  if (!hasResults.value) return '等待检测'
  return dotSupported.value ? 'DoT 检测完成' : 'DoT 不受支持'
})

const resultSubTitle = computed(() => {
  if (!hasResults.value) return '请输入 IP 地址开始检测'
  return dotSupported.value
    ? '该服务器支持 DoT，可以使用'
    : '该服务器不支持 DoT，建议更换服务器'
})

// 方法
const handleSubmit = async () => {
  if (!ipAddress.value || !isValidIP(ipAddress.value)) {
    error.value = '请输入合法的 IPv4 或 IPv6 地址！'
    // 重置数据
    leftItems.value.forEach(item => item.value = null)
    rightItems.value.forEach(item => item.value = null)
    return
  }

  loading.value = true
  error.value = ''
  warnings.value = [] // 清空预警

  try {
    const formData = new FormData()
    formData.append('ip', ipAddress.value)

    const response = await axios.post(
      'http://8.163.29.103:9000/dot-single-check',
      formData,
      {
        headers: {
          'Content-Type': 'multipart/form-data'
        }
      }
    )

    if (response.data.error) {
      throw new Error(response.data.error)
    }

    const data = response.data

    // 更新数据 - 左侧8个字段
    leftItems.value = [
      { label: '支持DoT', value: data.dotflag },
      { label: '证书有效性', value: data.cert_valid },
      { label: '自签名证书', value: data.self_signed },
      { label: '证书颁发机构', value: data.issuer },
      { label: '颁发机构国家', value: data.issuer_country },
      { label: '证书吊销状态', value: data.ocsp_status },
      { label: 'TLS版本', value: data.tls_version },
      { label: 'TLS加密套件', value: data.cipher_suite }
    ]

    // 更新数据 - 右侧8个字段
    rightItems.value = [
      { label: '关联域名', value: data.common_name },
      { label: '证书主体', value: data.subject },
      { label: '证书有效期（天）', value: data.validity_days },
      { label: '公钥长度（bit）', value: data.key_length },
      { label: '证书签名算法', value: data.signature_algorithm },
      { label: '协议版本', value: data.version },
      { label: '是否有应答', value: data.has_answer },
      { label: '响应时间（ms）', value: data.rtt_ms ? `${data.rtt_ms}ms` : null }
    ]

    // 检查预警
    checkWarnings(data)

    ElMessage.success('检测完成')
  } catch (err) {
    error.value = `检测失败: ${err.message || '网络错误'}`
    console.error('API Error:', err)
    ElMessage.error('获取数据失败，请检查 IP 或服务器状态')
  } finally {
    loading.value = false
  }
}

const checkWarnings = (data) => {
  warnings.value = []

  // 1. 证书有效期预警 - 小于100天预警
  if (data.validity_days && data.validity_days < 100) {
    warnings.value.push({
      type: 'certificate-expiring',
      title: '证书即将过期',
      description: `证书有效期仅剩 ${data.validity_days} 天，建议及时更新证书。`
    })
  }

  // 2. 自签名证书预警 - 是自签名需要预警
  if (data.self_signed === true) {
    warnings.value.push({
      type: 'self-signed-certificate',
      title: '自签名证书',
      description: '检测到自签名证书，可能存在安全风险。建议使用受信任的证书颁发机构签发的证书。'
    })
  }

  // 3. 颁发机构国家预警 - 不是CN需要预警
  if (data.issuer_country && data.issuer_country !== 'CN') {
    warnings.value.push({
      type: 'foreign-issuer',
      title: '境外证书颁发机构',
      description: `证书颁发机构位于 ${data.issuer_country}，非中国境内机构，请注意安全风险。`
    })
  }

  // 4. 证书签名算法预警 - MD5、SHA-1、DSA、RSA-1024、ECC-P192预警
  if (data.signature_algorithm) {
    const dangerousAlgorithms = ['MD5', 'SHA-1', 'DSA', 'RSA-1024', 'ECC-P192']
    const algorithm = data.signature_algorithm.toUpperCase()
    
    if (dangerousAlgorithms.some(dangerous => algorithm.includes(dangerous))) {
      warnings.value.push({
        type: 'weak-signature-algorithm',
        title: '弱签名算法',
        description: `证书使用了不安全的签名算法 ${data.signature_algorithm}，存在安全风险。`
      })
    }
  }

  // 5. TLS加密套件预警 - 出现SSL，RC4，3DES，CBC，MD5，SHA1，RSA，EXPORT，NULL关键字预警
  if (data.cipher_suite) {
    const dangerousKeywords = ['SSL', 'RC4', '3DES', 'CBC', 'MD5', 'SHA1', 'RSA', 'EXPORT', 'NULL']
    const cipherSuite = data.cipher_suite.toUpperCase()
    
    // 过滤掉安全的TLS版本引用，只检查真正的弱加密组件
    const foundDangerous = dangerousKeywords.filter(keyword => {
      if (keyword === 'SSL' && cipherSuite.includes('SSL')) {
        // 检查是否是SSL协议而不是TLS
        return !cipherSuite.includes('TLS')
      }
      return cipherSuite.includes(keyword)
    })
    
    if (foundDangerous.length > 0) {
      warnings.value.push({
        type: 'weak-cipher-suite',
        title: '弱加密套件',
        description: `TLS加密套件包含不安全的组件：${foundDangerous.join(', ')}，存在安全风险。`
      })
    }
  }

  // 6. TLS版本预警 - 不是TLS1.2或者1.3就需要预警
  if (data.tls_version) {
    const version = data.tls_version.toUpperCase()
    const isTLS12 = version.includes('TLS1.2') || version.includes('TLSV1.2') || version.includes('TLS 1.2')
    const isTLS13 = version.includes('TLS1.3') || version.includes('TLSV1.3') || version.includes('TLS 1.3')
    
    if (!isTLS12 && !isTLS13) {
      warnings.value.push({
        type: 'old-tls-version',
        title: '过时的TLS版本',
        description: `当前TLS版本为 ${data.tls_version}，建议使用TLS 1.2或TLS 1.3以确保安全。`
      })
    }
  }

  // 额外的证书有效性预警
  if (data.cert_valid === false) {
    warnings.value.push({
      type: 'certificate-invalid',
      title: '证书无效',
      description: '检测到的证书已过期或无效，可能存在安全风险。'
    })
  }
}
</script>

<style scoped>
.common-layout {
  min-height: 100vh;
  display: flex;
}

:deep(.el-container) {
  min-height: 100vh;
  width: 100%;
}

:deep(.el-main) {
  padding: 32px;
  background: #f6f8fc;
  display: flex;
  justify-content: center;
  align-items: flex-start;
}

.dot-container {
  padding: 40px;
  width: 90%;
  max-width: 1600px;
  margin: 20px auto;
}

.page-header {
  text-align: center;
  margin-bottom: 2rem;
}

.page-header h1 {
  color: #2c3e50;
  font-size: 2.5rem;
  margin: 0;
  font-weight: 600;
}

.subtitle {
  color: #606266;
  font-size: 1.1rem;
  margin-top: 0.5rem;
}

.search-card {
  margin-bottom: 2rem;
  border-radius: 12px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05);
}

.search-area {
  padding: 1rem;
}

:deep(.el-input-group__append) {
  padding: 0;
  
  .el-button {
    margin: 0;
    border: none;
    padding: 13px 20px;
  }
}

.error-alert {
  margin-bottom: 1rem;
}

.results-area {
  margin-top: 2rem;
}

.status-overview {
  margin-bottom: 2rem;
}

.quick-stats {
  display: flex;
  gap: 2rem;
  justify-content: center;
  margin-top: 1rem;
}

.stat-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 24px;
  border-radius: 8px;
  background: #f5f7fa;
  color: #909399;
  
  &.is-success {
    background: #f0f9eb;
    color: #67c23a;
  }
}

.detail-card {
  height: 100%;
  border-radius: 12px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05);
}

:deep(.el-descriptions) {
  padding: 0.5rem;
  
  .el-descriptions__label {
    width: 200px;
    color: #606266;
    font-weight: 500;
    white-space: nowrap;
  }
  
  .el-descriptions__content {
    padding: 12px 16px;
    min-width: 120px;
  }
}

:deep(.el-tag) {
  width: 100%;
  text-align: center;
  padding: 8px 16px;
  font-size: 0.9rem;
  min-width: 100px;
  font-weight: 500;
}

:deep(.el-empty) {
  padding: 4rem 0;
}

@media (max-width: 768px) {
  .dot-container {
    padding: 20px;
  }

  .page-header h1 {
    font-size: 2rem;
  }

  .quick-stats {
    flex-direction: column;
    gap: 1rem;
  }

  .stat-item {
    width: 100%;
    justify-content: center;
  }

  .warning-grid {
    grid-template-columns: 1fr;
    gap: 1rem;
  }
}

.warning-area {
  margin-bottom: 2rem;
}

.warning-header {
  border-radius: 12px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05);
  padding: 1rem;
}

.warning-content {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.warning-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5rem;
  margin-top: 1rem;
}

.warning-item {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  padding: 1.2rem;
  border-radius: 12px;
  background: #fffbe6;
  border: 1px solid #ffe58f;
  box-shadow: 0 2px 8px rgba(230, 162, 60, 0.1);
  transition: all 0.3s ease;
}

.warning-item:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 16px rgba(230, 162, 60, 0.15);
}

.warning-icon {
  font-size: 1.5rem;
  color: #e6a23c;
  margin-top: 0.2rem;
  flex-shrink: 0;
}

.warning-text {
  flex-grow: 1;
  min-width: 0;
}

.warning-title {
  font-weight: 600;
  font-size: 1rem;
  margin-bottom: 0.5rem;
  color: #e6a23c;
  line-height: 1.4;
}

.warning-desc {
  font-size: 0.9rem;
  color: #666;
  line-height: 1.5;
  word-wrap: break-word;
}
</style>